grammar BasicParser;
import BasicLexer;
@header { package cn.stevenyang.gen; }

numeric     : t=(INT | DECIMAL)                         #number;
assignment  : DIM ID AS astype (ASSIGN expression)?     #varDefine;
defparam    : ID AS ID (ASSIGN expression)?             #defParameters;

process     : expression (NEWLINE process)?             #genericExpression;

expression  : LPARENTHESES expression RPARENTHESES      #priority
            | expression DOT ID funccallparams          #objectAccess
            | NOT expression                            #logicNot
            | expression MULTIPLY expression            #arthmeticMultiply
            | expression DIVIDE expression              #arthmeticDivide
            | expression MOD expression                 #arthmeticMod
            | expression CONCATENATE expression         #concatenateStrStatement
            | expression ADD expression                 #arthmeticAdd
            | expression MINUS expression               #arthmeticMinus
            | expression EQ expression                  #compareEq
            | expression NEQ expression                 #compareNeq
            | expression GT expression                  #compareGt
            | expression LT expression                  #compareLt
            | expression LTE expression                 #compareLte
            | expression GTE expression                 #compareGte
            | expression BITAND expression              #logicBitAnd
            | expression XOR expression                 #logicXor
            | expression BITOR expression               #logicBitOr
            | expression AND expression                 #logicAnd
            | expression OR expression                  #logicOr
            | assignment                                #varDefineExpr
            | ifexpression                              #ifExpressionExpr
            | numeric                                   #num
            | STRING                                    #str
            | TRUE                                      #boolTrue
            | FALSE                                     #boolFalse
            | ME                                        #meSelf
            | forexpression                             #forExprStatement
            | foreachexpr                               #forEachExprStatement
            | whileexpression                           #whileExprStatement
            | defclass                                  #classDefStatement
            | array                                     #arrayDefStatement
            | map                                       #mapDefStatement
            | BREAK INT?                                #breakStatement
            | CONTINUE INT?                             #continueStatement
            | RETURN expression?                        #returnStatement
            | EXITSUB                                   #exitSubStatement
            | ID                                        #getVarExpr
            | ID funccallparams                         #functionCall
            | ID ASSIGN expression                      #assignStatement
            ;

funccallparams  : LPARENTHESES (expression (',' expression)*)? RPARENTHESES                                 #funcCallParamsExpr;
ifexpression    : IF expression THEN NEWLINE process NEWLINE elseifexpression* elseexpression? ENDIF        #ifExpr;
elseifexpression: ELSEIF expression THEN NEWLINE process? NEWLINE                                           #elseIfExpr;
elseexpression  : ELSE NEWLINE process? NEWLINE                                                             #elseExpr;
forexpression   : FOR ID ASSIGN expression t=(TO | DOWNTO) expression (STEP expression)? NEWLINE process? NEWLINE NEXT      #forExpr;
foreachexpr     : FOREACH ID AS astype OF expression NEWLINE process? NEWLINE ENDFOREACH                    #forEachExpression;
whileexpression : WHILE expression NEWLINE process? NEWLINE ENDWHILE                                        #whileExpr;
doloop          : DO NEWLINE process? NEWLINE WHILE expression LOOP                                         #doLoopExpr;
deffuncparam    : LPARENTHESES (defparam (',' defparam)*)? RPARENTHESES                                     #defFuncParamExpr;
sub             : SUB ID deffuncparam NEWLINE process? NEWLINE ENDSUB                                       #subroutineDefine;
func            : FUNCTION ID deffuncparam NEWLINE process? NEWLINE ENDFUNCTION                             #functionDefine;
impllist        : ID (',' ID)*                                                                              #implListExpr;
defclass        : CLASS ID (INHERITS ID)? (IMPLEMENTS impllist)? NEWLINE classbody? NEWLINE ENDCLASS        #defClassExpr;
accessclass     : PUBLIC | PROTECTED | PRIVATE                                                              #classAccessExpr;
classsub        : accessclass? SHARED? sub                                                                  #classSubExpr;
classfunc       : accessclass? SHARED? func                                                                 #classFuncExpr;
classvar        : accessclass? SHARED? ID                                                                   #classVarExpr;
classblock      : classsub | classfunc | classvar;
classbody       : classblock (NEWLINE classbody)?                                                           #classBodyExpr;

array           : '[' (expression (NEWLINE expression)*)? ']'                                                   #arrayDef;
map             : '{' (STRING MAP_ASSIGN expression (NEWLINE STRING MAP_ASSIGN expression)*)? '}'               #mapDef;

arraytype       : (ARRAY_SYMBOL)*                                                                           #arrayTypeDef;
astype          : ID arraytype                                                                              #asTypeDef;